package generate

import (
	"errors"
	"fmt"
	"gopkg.in/yaml.v3"
	"io"
	"operator/cicd/util"
	"strings"
)

type YamlType struct {
	Type string `yaml:"kind"`
}

type GenId int

const (
	deployment GenId = iota
	service
)

func getGenString(data string) (GenId, error) {
	switch data {
	case "Deployment", "deployment", "dep", "deploy":
		return deployment, nil
	case "Service", "svc", "service":
		return service, nil
	default:
		return 0, errors.New("not support this type")
	}
}

type YamlGenerator struct {
	generators map[GenId]Generator
}

func (yg *YamlGenerator) GenerateAll(data []byte, w io.Writer) error {
	arr := strings.Split(string(data), "---")
	length := len(arr)
	for index, y := range arr {
		_, _, err := yg.GenerateOne([]byte(y), w)
		if index < length-1 {
			_, err1 := w.Write([]byte("---\r"))
			if err1 != nil {
				continue
			}
		}

		if err != nil {
			fmt.Println(err)
			continue
		}
	}

	return nil
}

func (yg *YamlGenerator) GenerateOne(data []byte, w io.Writer) (count int, hasNext bool, err error) {
	arr := strings.SplitN(string(data), "---", 2)
	if len(arr) == 0 {
		return
	}
	if len(arr) > 1 {
		hasNext = true
	}

	one := []byte(arr[0])
	yt := &YamlType{}
	err = yaml.Unmarshal(one, yt)
	if err != nil {
		return 0, false, err
	}

	genString, err := getGenString(yt.Type)
	if err != nil {
		return 0, false, err
	}

	generate, err := yg.generators[genString].Generate(one, w)
	if err != nil {
		return 0, false, err
	}

	return generate, hasNext, nil
}

func NewYamlGenerator(config *util.CICDConfig) *YamlGenerator {
	m := make(map[GenId]Generator)
	deploy := NewDeploymentGenerator(config)
	m[deployment] = deploy

	svc := NewServiceGenerator(config)
	m[service] = svc

	return &YamlGenerator{
		generators: m,
	}
}
